//
//  ViewController.m
//  iview
//
//  Created by a on 15/12/19.
//  Copyright © 2015年 a. All rights reserved.
//

#import "AppDelegate.h"

#import "KCVideoViewController.h"

#import "QVAudioChannel.h"
#import "QVAudioDev.h"
#import "QVAudioCodec.h"

#import "QVVideoCapture.h"
#import "QVRender.h"

#import "QVVideoDecoder.h"
#import "QVVideoEncoder.h"

#import "QVVideoChannel.h"

#import "QuickVision.h"

@interface KCVideoViewController ()
{
    QVRender *mGLLayer;
    
    QVRender * mRender;
    QVVideoCapture * mVideoCapture;
    QVVideoEncoder * mVideoEncoder;
    QVVideoDecoder * mVideoDecoder;
    QVVideoChannel * mVideoChannel;
    
    QVAudioDev * mAudioDev;
    QVAudioCodec * mAudioCodec;
    QVAudioChannel * mAudioChannel;
    
    UINavigationItem * mBack;
    
    AppDelegate * mDelegate;
    
}

@end


@implementation KCVideoViewController

-(void) doBack {
    
    [mVideoChannel StopReceive];
    [mVideoChannel StopSend];
    
    [mVideoDecoder stop];
    [mVideoEncoder stop];

    [mVideoCapture StopCapture];


    [QVStream UnlinkStream:mVideoDecoder up:mVideoChannel direction:QV_DOWN_STREAM];
    [QVStream UnlinkStream:mVideoEncoder up:mVideoChannel direction:QV_UP_STREAM];
    [QVStream UnlinkStream:mVideoCapture up:mVideoEncoder direction:QV_UP_STREAM];
    
    [mVideoChannel uninitialize];
    
    [mAudioChannel StopReceive];
    [mAudioChannel StopSend];
    
    [mAudioCodec StopDecoder];
    [mAudioCodec StopEncoder];
    
    [mAudioDev StopPlayout];
    [mAudioDev StopCapture];
    
    [QVStream UnlinkStream:mAudioCodec up:mAudioChannel direction:QV_BOTH_STREAM];
    [QVStream UnlinkStream:mAudioDev up:mAudioCodec direction:QV_BOTH_STREAM];

    [mAudioChannel uninitialize];

    [mAudioCodec uninitialize];
    
    [mAudioDev uninitialize];
    
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)viewDidLoad {
    //[super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    QuickVision * vision = [QuickVision GetInstance];
    [vision Init:@"d82711e24c0de83b722133769143caeb"];
    
    mDelegate = [[UIApplication sharedApplication] delegate];
    
    self.navigationItem.title = @"Video";
    
    
    CGRect status = [[UIApplication sharedApplication] statusBarFrame];
    CGRect nav = self.navigationController.navigationBar.frame;
    
    mBack = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIButtonTypeSystem target:self action:@selector(doBack)];
    
    self.navigationItem.leftBarButtonItem = mBack;
    
    
    _viewDec = [[UIView alloc] initWithFrame:CGRectMake(0, status.size.height + nav.size.height, self.view.frame.size.width, self.view.frame.size.height - status.size.height - nav.size.height)];
    _viewDec.backgroundColor = [UIColor blackColor];
    [self.view addSubview:_viewDec];
    
    mGLLayer = [[QVRender alloc] initWithFrame:_viewDec.bounds];
    [_viewDec.layer addSublayer:mGLLayer];
    
    _viewPreview = [[UIView alloc] initWithFrame:CGRectMake(0, status.size.height + nav.size.height, self.view.frame.size.width / 4, self.view.frame.size.height / 4)];
    
    _viewPreview.backgroundColor = [UIColor blackColor];
    [self.view addSubview:_viewPreview];
    
    const char * ip = [mDelegate->mIpAddr UTF8String];

    
    //QVFormat * audioFormat = [QVFormat CreateAudioFormat:"ILBC" sample:8000 channel:1];
    //[audioFormat SetInteger:KEY_BIT_RATE value:13300];
    
    // @"    PCMU", @"    PCMA", @"    ILBC", @"    OPUS", @"    ISAC", @"    G722", nil];
    QVFormat * audioSendFormat = [QVFormat Create];
    switch (mDelegate->mAudioSend) {
        case 0: // PCMU
            [audioSendFormat SetString:KEY_PLNAME value:"PCMU"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:64000];
            break;
            
        case 1: // PCMA
            [audioSendFormat SetString:KEY_PLNAME value:"PCMA"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:64000];
           
            break;
            
        case 2: // ILBC
            [audioSendFormat SetString:KEY_PLNAME value:"ILBC"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:13300];
            break;
            
        case 3: // OPUS
            [audioSendFormat SetString:KEY_PLNAME value:"OPUS"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:48000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:2];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:64000];

            break;
            
        case 4: // ISAC
            [audioSendFormat SetString:KEY_PLNAME value:"ISAC"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:16000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:32000];

            break;
            
        case 5: // G722
            [audioSendFormat SetString:KEY_PLNAME value:"G722"];
            [audioSendFormat SetInteger:KEY_SAMPLE_RATE value:16000];
            [audioSendFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioSendFormat SetInteger:KEY_BIT_RATE value:64000];
            break;
            
        default:
            break;
    }
    
    QVFormat * audioReceiveFormat = [QVFormat Create];
    switch (mDelegate->mAudioReceive) {
        case 0: // PCMU
            [audioReceiveFormat SetString:KEY_PLNAME value:"PCMU"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:64000];
            break;
            
        case 1: // PCMA
            [audioReceiveFormat SetString:KEY_PLNAME value:"PCMA"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:64000];
            
            break;
            
        case 2: // ILBC
            [audioReceiveFormat SetString:KEY_PLNAME value:"ILBC"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:8000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:13300];
            break;
            
        case 3: // OPUS
            [audioReceiveFormat SetString:KEY_PLNAME value:"OPUS"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:48000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:2];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:64000];
            
            
            break;
            
        case 4: // ISAC
            [audioReceiveFormat SetString:KEY_PLNAME value:"ISAC"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:16000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:32000];
            
            break;
            
        case 5: // G722
            [audioReceiveFormat SetString:KEY_PLNAME value:"G722"];
            [audioReceiveFormat SetInteger:KEY_SAMPLE_RATE value:16000];
            [audioReceiveFormat SetInteger:KEY_CHANNEL_NUMBER value:1];
            [audioReceiveFormat SetInteger:KEY_BIT_RATE value:64000];
            
            break;
            
        default:
            break;
    }
    
     mAudioDev = [[QVAudioDev alloc] init];
     
     QVFormat * devFmt = [QVFormat Create];
     [devFmt SetInteger:KEY_SAMPLE_RATE value:48000];
     
     [mAudioDev initializeWithFormat:devFmt];
     
     mAudioCodec = [[QVAudioCodec alloc] init];
     [mAudioCodec initializeWithID:0];

    [mAudioCodec SetEncoderCodec:audioSendFormat];
    [mAudioCodec SetDecoderCodec:audioReceiveFormat];
    
    [QVStream LinkStream:mAudioDev up:mAudioCodec direction:QV_BOTH_STREAM];
    
    mAudioChannel = [[QVAudioChannel alloc] init];
    [mAudioChannel initializeWithID:0];
    [mAudioChannel SetSendCodec:audioSendFormat];
    [mAudioChannel SetReceiveCodec:audioReceiveFormat];
    
    [mAudioChannel InitialSendSocket:ip port:6000];
    [mAudioChannel InitialReceiveSocket:6000];
    
    [QVStream LinkStream:mAudioCodec up:mAudioChannel direction:QV_BOTH_STREAM];
    
    [mAudioChannel RegisterCodec:mAudioCodec];
    
    [mAudioCodec SetFECStatus:true];
    [mAudioChannel SetREDStatus:true];
    [mAudioChannel SetNACKStatus:true];
    
    [mAudioChannel StartReceive];
    [mAudioChannel StartSend];
    
    [mAudioCodec StartDecoder];
    [mAudioCodec StartEncoder];

    [mAudioDev StartCapture];
    [mAudioDev StartPlayout];
    
    mVideoCapture = [[QVVideoCapture alloc] init];
    [mVideoCapture InitializeWith:0 ViewCtrl:_viewPreview];
    [mVideoCapture StartCapture:mDelegate->mVideoWidth height:mDelegate->mVideoHeight fps:30];
    
    mVideoEncoder = [[QVVideoEncoder alloc] init];
    [mVideoEncoder initWithConfiguration:mDelegate->mVideoWidth height:mDelegate->mVideoHeight framerate:30 bitrate:mDelegate->mBitRate];
    [mVideoEncoder start];
    
    mRender = [[QVRender alloc] initWithFrame:_viewDec.bounds];
    
    mVideoDecoder = [[QVVideoDecoder alloc] init];
    [mVideoDecoder initializeWith:mDelegate->mVideoWidth height:mDelegate->mVideoHeight bitrate:mDelegate->mBitRate render:mGLLayer];
    [mVideoDecoder start];
    
    mVideoChannel = [[QVVideoChannel alloc] init];
    
    [QVStream LinkStream:mVideoCapture up:mVideoEncoder direction:QV_UP_STREAM];
    
    QVFormat * videoFormat = [QVFormat CreateVideoFormat:kH264PLName width:mDelegate->mVideoWidth height:mDelegate->mVideoHeight];
    mVideoChannel = [[QVVideoChannel alloc] init];
    [mVideoChannel initializeWithID:1];
    [mVideoChannel SetSendCodec:videoFormat];
    [mVideoChannel SetReceiveCodec:videoFormat];
    [mVideoChannel InitialSendSocket:ip port:8000];
    [mVideoChannel InitialReceiveSocket:8000];
    
    //[QVStream LinkStream:mVideoEncoder up:mVideoDecoder direction:QV_UP_STREAM];
    [QVStream LinkStream:mVideoEncoder up:mVideoChannel direction:QV_UP_STREAM];
    [QVStream LinkStream:mVideoDecoder up:mVideoChannel direction:QV_DOWN_STREAM];
    
    [mVideoChannel StartReceive];
    [mVideoChannel StartSend];


}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
